﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Newtonsoft.Json;

namespace CrazyBubbleToolkit
{

    #region 泡泡球类型定义
    /// <summary>
    /// 球类型
    /// </summary>
    public enum BubbleType
    {
        Empty = 0,

        RedBubble = 10,
        YellowBubble,
        BlueBubble,
        GreenBubble,
        PurpleBubble,
        BlackBubble,
        RanBubble,
        RanBubble_Red,
        RanBubble_Yellow,
        RanBubble_Blue,
        RanBubble_Green,                    //20
        RanBubble_Purple,

        RedBubble_Fog = RedBubble + 100,    //110
        YellowBubble_Fog,
        BlueBubble_Fog,
        GreenBubble_Fog,
        PurpleBubble_Fog,
        BlackBubble_Fog,
        RanBubble_Fog,
        RanBubble_Red_Fog,
        RanBubble_Yellow_Fog,
        RanBubble_Blue_Fog,
        RanBubble_Green_Fog,                //120
        RanBubble_Purple_Fog,

        Frog = 300,
        Ghost,
        Arcane,
        Thunder,
        Xuanwo,

        Animal = 400,
        MAnimalTop = 500,
        MAnimal = 501,
        LAnimalCenter = 600,
        LAnimal,

        //卡牌泡泡定义
        MonkeyBubble = 700,
        MouseBubble,
        RabbitBubble,
        BearBubble,
        FishBubble,

        //新增特殊道具球，分别为星星球1-5，特殊球1-4, 丝带球1-5
        //-----------------------------------------------------------------------
        star1Bubble = 750,
        star2Bubble,
        star3Bubble,
        star4Bubble,
        star5Bubble,
        s1Bubble,
        s2Bubble,
        s3Bubble,
        s4Bubble,
        s5Bubble,

        Silk1Bubble = 760,
        Silk2Bubble,
        Silk3Bubble,
        Silk4Bubble,
        Silk5Bubble,

        s6Bubble = 766,
        s7Bubble,
        s8Bubble,
        s9Bubble,
        s10Bubble,
        s11Bubble,
        s12Bubble,
        s13Bubble,
        s14Bubble,
        s15Bubble,
        //-----------------------------------------------------------------------
    }
    #endregion


    #region 自定义类型
    public class Bubble         //球
    {
        [JsonProperty("t")]
        public int Type { get; set; }
    }

    public class AnimalGroup    //动物
    {
        public int x { get; set; }
        public int y { get; set; }

        //0:小动物，1：中动物，2：大动物
        public int type { get; set; }
    }

    public class DistanceSpeed
    {
        public int d { get; set; }    //距离
        public int s { get; set; }    //速度
    }

    /// <summary>
    /// 为特定的球S8添加，旋转速度和角度属性
    /// </summary>
    public class RotatingSpeedAngle
    {
        //public int x { get; set; }      //行坐标
        //public int y { get; set; }      //列坐标

        [JsonProperty("s")]
        public int speed { get; set; }  //旋转速度

        [JsonProperty("a")]
        public int angle { get; set; }  //旋转角度

        //public RotatingSpeedAngle(int x, int y, int speed, int angle)
        public RotatingSpeedAngle(int speed, int angle)
        {
            //this.x = x;
            //this.y = y;
            this.speed = speed;
            this.angle = angle;
        }
    }

    #endregion


    #region stage总体信息预览，MainWindow
    /// <summary>
    /// 用于整体显示关卡信息
    /// </summary>
    public class Stage : INotifyPropertyChanged
    {
        public string Index { get; set; }       // 大关编号
        public string SubIndex { get; set; }    // 子关编号

        private string _Name;           //名称
        public string Name
        {
            get
            {
                return _Name;
            }
            set
            {
                if (value != _Name)
                {
                    _Name = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Name"));    //当变量赋值时，用Handler更新绑定的"Name"属性,
                }
            }
        }


        private string _Status;         //状态
        public string Status
        {
            get
            {
                return _Status;
            }
            set
            {
                if (value != _Status)
                {
                    _Status = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Status"));
                }
            }
        }


        private string _Type;           //类型
        public string Type
        {
            get
            {
                return _Type;
            }
            set
            {
                if (value != _Type)
                {
                    _Type = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Type"));
                }
            }
        }

        private bool _CanClear = false; //清空
        public bool CanClear
        {
            get
            {
                return _CanClear;
            }
            set
            {
                if (value != _CanClear)
                {
                    _CanClear = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("CanClear"));
                }
            }
        }

        private bool _CanCopy = false;  //复制
        public bool CanCopy
        {
            get
            {
                return _CanCopy;
            }
            set
            {
                if (value != _CanCopy)
                {
                    _CanCopy = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("CanCopy"));
                }
            }
        }

        private bool _CanPaste = false; //粘贴
        public bool CanPaste
        {
            get
            {
                return _CanPaste;
            }
            set
            {
                if (value != _CanPaste)
                {
                    _CanPaste = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("CanPaste"));
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
    #endregion


    #region 关卡数据定义

    /// <summary>
    /// 关卡数据定义
    /// </summary>
    public class StageData
    {

        #region 数据变量类型定义
        //关卡类型
        //0,1,2
        [JsonProperty("gt")]
        public int GridsType { get; set; }

        //下落速度
        [JsonProperty("moveSpeed")]
        public int moveSpeed { get; set; }

        //控制距离速度数组，第一项为总的组数，其后各项依次为距离和速度
        [JsonProperty("distanceSpeed")]
        public List<DistanceSpeed> distanceSpeed { get; set; }

        /// <summary>
        /// 特定类型球S8Bubble的旋转速度和角度属性数据
        /// </summary>
        [JsonProperty("rotatingSpeedAngle")]
        //public List<RotatingSpeedAngle> rotatingSpeedAngle { get; set; }
        public Dictionary<string, RotatingSpeedAngle> rotatingSpeedAngle { get; set; }

        //控制开关, 出球算法类型选择
        [JsonProperty("switch1")]
        public int switch1 { get; set; }

        //控制开关, 球数设置
        [JsonProperty("switch2")]
        public int switch2 { get; set; }

        //控制开关, 出球行数设置
        [JsonProperty("switch3")]
        public int switch3 { get; set; }

        //控制开关, 炮筒转动速度
        [JsonProperty("switch4")]
        public int switch4 { get; set; }

        //控制开关, 炮筒转动角度
        [JsonProperty("switch5")]
        public int switch5 { get; set; }

        //允许随机颜色数
        [JsonProperty("rc")]
        public int RanColors { get; set; }

        //实际出现的颜色数组
        [JsonProperty("uc")]
        public List<int> UsedColors { get; set; }

        //任务目标数值
        [JsonProperty("goal")]
        public int Goal { get; set; }

        //泡泡地图矩阵，由上至下 
        [JsonProperty("grids")]
        public List<List<Bubble>> BubbleGrids { get; set; }

        //动物分组
        [JsonProperty("animals")]
        public List<AnimalGroup> AnimalGroup { get; set; }

        //可用炮弹总数
        [JsonProperty("bc")]
        public int TotalBullets { get; set; }

        //各种炮弹随机比率，100分制
        [JsonProperty("r0")]
        public int BulletRedRatio { get; set; }

        [JsonProperty("r1")]
        public int BulletYellowRatio { get; set; }

        [JsonProperty("r2")]
        public int BulletBlueRatio { get; set; }

        [JsonProperty("r3")]
        public int BulletGreenRatio { get; set; }

        [JsonProperty("r4")]
        public int BulletPurpleRatio { get; set; }

        //1星最低分
        [JsonProperty("s1")]
        public int Star1 { get; set; }

        //2星最低分
        [JsonProperty("s2")]
        public int Star2 { get; set; }

        //3星最低分
        [JsonProperty("s3")]
        public int Star3 { get; set; }

        #endregion

        //构造函数
        public StageData()
        {
            BubbleGrids = new List<List<Bubble>>();     //编辑界面中的球数据

            RanColors = 5;                              //初始随机颜色数
            UsedColors = new List<int>();               //已使用的球
            distanceSpeed = new List<DistanceSpeed>();  //距离速度控制

            //为特定类型球S8Bubble，添加旋转速度和角度属性数据
            //rotatingSpeedAngle = new List<RotatingSpeedAngle>();
            rotatingSpeedAngle = new Dictionary<string, RotatingSpeedAngle>();
        }

        //获取坐标处的球
        public Bubble GetBubble(int row, int col)
        {
            return BubbleGrids[row][col];
        }

        //设置坐标处的球
        public void SetBubble(BubbleType t, int row, int col)
        {
            int linesToExpand = row - BubbleGrids.Count + 1;
            for (int i = 0; i < linesToExpand; i++)
            {
                var line = new List<Bubble>();
                if ((BubbleGrids.Count - 1) % 2 == 0)
                {
                    //当前最大行为偶数行
                    for (int c = 0; c < 10; c++)
                    {
                        line.Add(new Bubble());
                    }
                }
                else
                {
                    //当前最大行为奇数行
                    for (int c = 0; c < 11; c++)
                    {
                        line.Add(new Bubble());
                    }
                }
                BubbleGrids.Add(line);
            }

            BubbleGrids[row][col].Type = (int)t;
        }

        //if (t == BubbleType.s8Bubble) updateRotateSpeedAngleAttr(row, row);
        /// <summary>
        /// 更新坐标处s8Bubble的旋转速度和角度属性
        /// </summary>
        public void updateRotateSpeedAngleAttr(int row, int col, string speed, string angle)
        {
            updateRotateSpeedAngleAttr(row, col, ParseInt(speed), ParseInt(angle));
        }

        /// <summary>
        /// 更新坐标处s8Bubble的旋转速度和角度属性
        /// </summary>
        public void updateRotateSpeedAngleAttr(int row, int col, int speed, int angle)
        {
            string key = row + "_" + col;
            if (rotatingSpeedAngle.ContainsKey(key)) rotatingSpeedAngle.Remove(key);
            //RotatingSpeedAngle value = new RotatingSpeedAngle(row, col, speed, angle);
            RotatingSpeedAngle value = new RotatingSpeedAngle(speed, angle);
            rotatingSpeedAngle.Add(key, value);
        }

        /// <summary>
        /// 移除坐标处s8Bubble的旋转速度和角度属性
        /// </summary>
        public void RemoveRotateSpeedAngleAttr(int row, int col)
        {
            string key = row + "_" + col;
            if (rotatingSpeedAngle.ContainsKey(key)) rotatingSpeedAngle.Remove(key);
        }

        /// <summary>
        /// 获取指定坐标处的旋转速度和角度属性值
        /// </summary>
        public int[] getRotateSpeedAngle(int row, int col)
        {
            string key = row + "_" + col;
            if (rotatingSpeedAngle.ContainsKey(key))
            {
                RotatingSpeedAngle value = rotatingSpeedAngle[key];
                return new int[] { value.speed, value.angle };
            }
            else return new int[] { 0, 0 };
        }

        public int ParseInt(String str)
        {
            int n = 0;

            try { n = Int32.Parse(str); }
            catch (Exception) { }

            return n;
        }

        //数据压缩， 序列化成json前，需要调用此函数来压缩数据，使得生成的json体积缩小
        public void Compress()
        {
            int maxLine = BubbleGrids.Count - 1;

            for (int r = maxLine; r >= 0; r--)
            {
                bool emptyLine = true;
                for (int c = 0; c < BubbleGrids[r].Count; c++)
                {
                    if (BubbleGrids[r][c].Type != (int)BubbleType.Empty)
                    {
                        emptyLine = false;
                        break;
                    }
                }
                if (emptyLine)
                {
                    //删除该行
                    BubbleGrids.RemoveAt(r);
                }
                else
                {
                    break;
                }
            }

            //同步animal group
            AnimalGroup = new List<AnimalGroup>();
            for (int r = 0; r < BubbleGrids.Count; r++)
            {
                var line = BubbleGrids[r];
                for (int col = 0; col < line.Count; col++)
                {
                    var bubble = line[col];
                    var type = (BubbleType)bubble.Type;
                    if (type == BubbleType.Animal)
                    {
                        AnimalGroup.Add(new AnimalGroup
                        {
                            x = col,
                            y = r,
                            type = 0
                        });
                    }
                    else if (type == BubbleType.MAnimalTop)
                    {
                        AnimalGroup.Add(new AnimalGroup
                        {
                            x = col,
                            y = r,
                            type = 1
                        });
                    }
                    else if (type == BubbleType.LAnimalCenter)
                    {
                        AnimalGroup.Add(new AnimalGroup
                        {
                            x = col,
                            y = r,
                            type = 2
                        });
                    }
                }

            }

        }
    }
    #endregion

}
